package com.lagou.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.lagou.common.constant.CacheDefine;
import com.lagou.common.util.ConvertUtils;
import com.lagou.common.util.ValidateUtils;
import com.lagou.course.api.CourseRemoteService;
import com.lagou.course.api.dto.ActivityCourseDTO;
import com.lagou.course.api.dto.CourseDTO;
import com.lagou.course.api.enums.CourseStatus;
import com.lagou.order.api.dto.CreateShopGoodsOrderReqDTO;
import com.lagou.order.api.dto.UserCourseOrderDTO;
import com.lagou.order.api.dto.UserCourseOrderResDTO;
import com.lagou.order.api.enums.UserCourseOrderSourceType;
import com.lagou.order.api.enums.UserCourseOrderStatus;
import com.lagou.order.entity.UserCourseOrder;
import com.lagou.order.mapper.UserCourseOrderMapper;
import com.lagou.order.service.IUserCourseOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lagou.order.util.IDUtil;
import io.jsonwebtoken.lang.Collections;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 用户课程订单表 服务实现类
 * </p>
 *
 * @author dingchengyu
 * @since 2022-02-19
 */
@Service
@Slf4j
public class UserCourseOrderServiceImpl extends ServiceImpl<UserCourseOrderMapper, UserCourseOrder> implements IUserCourseOrderService {

    @Autowired
    private CourseRemoteService courseRemoteService;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public UserCourseOrderResDTO saveOrder(CreateShopGoodsOrderReqDTO reqDTO) {
        //校验商品信息
        CourseDTO courseDTO = courseRemoteService.getUserCourseById(reqDTO.getGoodsId(),reqDTO.getUserId());
        log.info("saveOrder - courseRemoteService.getCourseById - goodsId:{} courseDTO:{}",reqDTO.getGoodsId(),JSON.toJSONString(courseDTO));
        ValidateUtils.isFalse(null == courseDTO, "课程信息为空");
        ValidateUtils.isTrue(courseDTO.getStatus().equals(CourseStatus.PUTAWAY.getCode()), "课程状态错误");
        UserCourseOrder userCourseOrder = checkSuccessBuyGoods(reqDTO.getGoodsId(), reqDTO.getUserId());
        ValidateUtils.isTrue(null == userCourseOrder, "已成功购买过该课程");
        userCourseOrder = checkCreateBuyGoods(reqDTO.getGoodsId(), reqDTO.getUserId());
        if(null != userCourseOrder) {
            //已经下单还有效
            return new UserCourseOrderResDTO(userCourseOrder.getOrderNo());
        }
        //创建商品订单
        UserCourseOrder saveOrder = buildUserCourseOrder(reqDTO.getGoodsId(), reqDTO.getUserId(), reqDTO.getSourceType());
        String activityCourseStr = redisTemplate.opsForValue().get(CacheDefine.ActivityCourse.getKey(reqDTO.getGoodsId()));
        ActivityCourseDTO activityCourseCache = null;
        if(StringUtils.isNotBlank(activityCourseStr)) {
            activityCourseCache = JSON.parseObject(activityCourseStr, ActivityCourseDTO.class);
            Long cacheRes = redisTemplate.opsForValue().increment(CacheDefine.ActivityCourse.getStockKey(activityCourseCache.getCourseId()), -1L);
            log.info("saveOrder - increment - activityCourseId:{} courseId:{} cacheRes:{}",activityCourseCache.getId(),reqDTO.getGoodsId(),cacheRes);
            if(cacheRes >= 0) {
                saveOrder.setActivityCourseId(activityCourseCache.getId());
            }else {
                redisTemplate.opsForValue().increment(CacheDefine.ActivityCourse.getStockKey(activityCourseCache.getId()), 1L);
            }
        }
        try {
            save(saveOrder);
        } catch (Exception e) {
            log.error("saveOrder - reqDTO:{} err",JSON.toJSONString(reqDTO),e);
            //异常还原库存
            if(saveOrder.getActivityCourseId() != null) {
                redisTemplate.opsForValue().increment(CacheDefine.ActivityCourse.getStockKey(activityCourseCache.getId()), 1L);
            }
            ValidateUtils.isTrue(false, "课程订单处理失败");
        }
        //发送MQ
        if(saveOrder.getActivityCourseId() != null) {
//            rocketMqService.convertAndSend(MQConstant.Topic.ACTIVITY_COURSE_STOCK,
//                    new BaseMqDTO<ActivityCourseUpdateStockDTO>(new ActivityCourseUpdateStockDTO(saveOrder.getActivityCourseId()), UUID.randomUUID().toString()));
        }
        return new UserCourseOrderResDTO(saveOrder.getOrderNo());
    }

    @Override
    public UserCourseOrderDTO getCourseOrderByOrderNo(String orderNo) {
        ValidateUtils.notNullParam(orderNo);
        UserCourseOrder userCourseOrderDB = getOne(new QueryWrapper<UserCourseOrder>().eq("order_no", orderNo));
        ValidateUtils.isTrue(null != userCourseOrderDB, "商品订单信息查询为空");
        return ConvertUtils.convert(userCourseOrderDB, UserCourseOrderDTO.class);
    }

    @Override
    public void updateOrderStatus(String orderNo, Integer status) {
        ValidateUtils.notNullParam(orderNo);
        ValidateUtils.notNullParam(status);

        UserCourseOrder uerCourseOrderDB = getOne(new QueryWrapper<UserCourseOrder>().eq("order_no", orderNo));
        ValidateUtils.isTrue(null != uerCourseOrderDB, "商品订单信息查询为空");

        if(uerCourseOrderDB.getStatus().equals(status)) {
            return;
        }
        if(uerCourseOrderDB.getStatus().equals(UserCourseOrderStatus.SUCCESS.getCode())) {
            return;
        }
        UserCourseOrder updateUerCourseOrder = new UserCourseOrder();
        updateUerCourseOrder.setId(uerCourseOrderDB.getId());
        updateUerCourseOrder.setStatus(status);

        ValidateUtils.isTrue(updateById(updateUerCourseOrder), "更新商品订单信息查询失败");
    }

    @Override
    public List<UserCourseOrderDTO> getUserCourseOrderByUserId(Integer userId) {
        ValidateUtils.notNullParam(userId);
        ValidateUtils.isTrue(userId > 0, "用户id错误");
        List<UserCourseOrder> userCourseOrderList = list(new QueryWrapper<UserCourseOrder>().eq("user_id", userId).eq("status", UserCourseOrderStatus.SUCCESS.getCode()).orderByDesc("id"));
        if(CollectionUtils.isEmpty(userCourseOrderList)) {
            return Lists.newArrayList();
        }
        return ConvertUtils.convertList(userCourseOrderList, UserCourseOrderDTO.class);
    }

    @Override
    public Integer countUserCourseOrderByCoursIds(Integer userId, List<Integer> coursIds) {
        ValidateUtils.notNullParam(userId);
        ValidateUtils.isTrue(userId > 0, "用户id错误");
        return count(new QueryWrapper<UserCourseOrder>().eq("user_id", userId).in("course_id", coursIds).eq("status", UserCourseOrderStatus.SUCCESS.getCode()));
    }

    @Override
    public Integer countUserCourseOrderByCourseId(Integer coursId) {
        ValidateUtils.notNullParam(coursId);
        ValidateUtils.isTrue(coursId > 0, "课程id错误");
        return count(new QueryWrapper<UserCourseOrder>().eq("course_id", coursId).eq("status", UserCourseOrderStatus.SUCCESS.getCode()));
    }

    @Override
    public List<UserCourseOrderDTO> getOrderListByCourseId(Integer coursId) {
        ValidateUtils.notNullParam(coursId);
        ValidateUtils.isTrue(coursId > 0, "课程id错误");

        List<UserCourseOrder> userCourseOrderList = list(new QueryWrapper<UserCourseOrder>().eq("course_id", coursId).eq("status", UserCourseOrderStatus.SUCCESS.getCode()));
        if(Collections.isEmpty(userCourseOrderList)) {
            return Lists.newArrayList();
        }

        return ConvertUtils.convertList(userCourseOrderList, UserCourseOrderDTO.class);
    }

    /**
     * 构建商品订单信息
     * @param goodId
     * @param userId
     * @param sourceType
     * @return
     */
    UserCourseOrder buildUserCourseOrder(Integer goodId, Integer userId, UserCourseOrderSourceType sourceType){
        UserCourseOrder saveUserCourseOrder = new UserCourseOrder();
        saveUserCourseOrder.setId(IDUtil.getRandomId());
        saveUserCourseOrder.setCourseId(goodId);
        saveUserCourseOrder.setCreateTime(new Date());
        saveUserCourseOrder.setOrderNo(IDUtil.getRandomId().toString());
        saveUserCourseOrder.setSourceType(sourceType.getCode());
        saveUserCourseOrder.setUpdateTime(saveUserCourseOrder.getCreateTime());
        saveUserCourseOrder.setUserId(userId);
        return saveUserCourseOrder;
    }

    /**
     * 查询用户成功状态订单
     * @param goodId
     * @param userId
     * @return
     */
    UserCourseOrder checkSuccessBuyGoods(Integer goodId,Integer userId) {
        ValidateUtils.notNullParam(userId);
        ValidateUtils.isTrue(userId > 0, "用户id错误");
        ValidateUtils.notNullParam(goodId);
        ValidateUtils.isTrue(goodId > 0, "课程id错误");
        return getOne(new QueryWrapper<UserCourseOrder>()
                .eq("course_id", goodId)
                .eq("user_id", userId)
                .eq("status", UserCourseOrderStatus.SUCCESS.getCode()));
    }

    /**
     * 查询用户新建状态订单
     * @param goodId
     * @param userId
     * @return
     */
    UserCourseOrder checkCreateBuyGoods(Integer goodId,Integer userId) {
        ValidateUtils.notNullParam(userId);
        ValidateUtils.isTrue(userId > 0, "用户id错误");
        ValidateUtils.notNullParam(goodId);
        ValidateUtils.isTrue(goodId > 0, "课程id错误");
        return getOne(new QueryWrapper<UserCourseOrder>()
                .eq("course_id", goodId)
                .eq("user_id", userId)
                .eq("status", UserCourseOrderStatus.CREATE.getCode()));
    }

}
